<template>
  <div 
    ref="lottieContainer" 
    class="lottie-container"
    :class="[containerClass, { 'loading': isLoading, 'error': hasError }]"
    :style="containerStyle"
  >
    <!-- 加载状态 -->
    <div v-if="isLoading" class="loading-overlay">
      <div class="loading-spinner"></div>
      <p class="loading-text">{{ loadingText }}</p>
    </div>
    
    <!-- 错误状态 -->
    <div v-if="hasError" class="error-overlay">
      <div class="error-icon">⚠️</div>
      <p class="error-message">{{ errorMessage }}</p>
      <button 
        v-if="enableRetry" 
        @click="retry" 
        class="retry-button"
        :disabled="isRetrying"
      >
        {{ isRetrying ? retryingText : retryText }}
      </button>
    </div>
  </div>
</template>

<script>
import lottie from 'lottie-web'

export default {
  name: 'LottieAnimation',
  props: {
    // 动画数据或路径
    animationData: {
      type: [Object, String],
      required: true
    },
    // 是否自动播放
    autoplay: {
      type: Boolean,
      default: true
    },
    // 是否循环
    loop: {
      type: Boolean,
      default: true
    },
    // 播放速度
    speed: {
      type: Number,
      default: 1
    },
    // 容器宽度
    width: {
      type: [String, Number],
      default: '100%'
    },
    // 容器高度
    height: {
      type: [String, Number],
      default: '100%'
    },
    // 渲染器类型
    renderer: {
      type: String,
      default: 'svg',
      validator: value => ['svg', 'canvas', 'html'].includes(value)
    },
    // 额外的CSS类
    containerClass: {
      type: String,
      default: ''
    },
    // 是否响应鼠标悬停
    hoverToPlay: {
      type: Boolean,
      default: false
    },
    // 播放方向 1: 正向, -1: 反向
    direction: {
      type: Number,
      default: 1,
      validator: value => [1, -1].includes(value)
    },
    // 是否启用重试功能
    enableRetry: {
      type: Boolean,
      default: true
    },
    // 最大重试次数
    maxRetries: {
      type: Number,
      default: 3
    },
    // 重试延迟时间（毫秒）
    retryDelay: {
      type: Number,
      default: 1000
    },
    // 加载文本
    loadingText: {
      type: String,
      default: '加载动画中...'
    },
    // 重试按钮文本
    retryText: {
      type: String,
      default: '重试'
    },
    // 重试中文本
    retryingText: {
      type: String,
      default: '重试中...'
    }
  },
  data() {
    return {
      animation: null,
      isHovered: false,
      isLoading: false,
      hasError: false,
      errorMessage: '',
      retryCount: 0,
      isRetrying: false
    }
  },
  computed: {
    containerStyle() {
      return {
        width: typeof this.width === 'number' ? `${this.width}px` : this.width,
        height: typeof this.height === 'number' ? `${this.height}px` : this.height
      }
    }
  },
  mounted() {
    this.initAnimation()
    
    if (this.hoverToPlay) {
      this.setupHoverEvents()
    }
  },
  beforeUnmount() {
    this.destroyAnimation()
  },
  watch: {
    animationData() {
      this.destroyAnimation()
      this.initAnimation()
    },
    speed(newSpeed) {
      if (this.animation) {
        this.animation.setSpeed(newSpeed)
      }
    },
    direction(newDirection) {
      if (this.animation) {
        this.animation.setDirection(newDirection)
      }
    }
  },
  methods: {
    async initAnimation() {
      this.isLoading = true
      this.hasError = false
      this.errorMessage = ''
      
      try {
        let animationData = this.animationData
        
        // 如果是字符串路径，则加载JSON文件
        if (typeof animationData === 'string') {
          const response = await fetch(animationData)
          if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`)
          }
          animationData = await response.json()
        }
        
        // 验证动画数据
        if (!animationData || typeof animationData !== 'object') {
          throw new Error('无效的动画数据格式')
        }
        
        this.animation = lottie.loadAnimation({
          container: this.$refs.lottieContainer,
          renderer: this.renderer,
          loop: this.loop,
          autoplay: this.autoplay && !this.hoverToPlay,
          animationData: animationData,
          rendererSettings: {
            preserveAspectRatio: 'xMidYMid slice'
          }
        })
        
        // 设置播放速度和方向
        this.animation.setSpeed(this.speed)
        this.animation.setDirection(this.direction)
        
        // 绑定事件
        this.animation.addEventListener('complete', this.onComplete)
        this.animation.addEventListener('loopComplete', this.onLoopComplete)
        this.animation.addEventListener('enterFrame', this.onEnterFrame)
        this.animation.addEventListener('data_ready', this.onDataReady)
        this.animation.addEventListener('data_failed', this.onDataFailed)
        
        this.isLoading = false
        this.retryCount = 0
        this.$emit('animationCreated', this.animation)
        
      } catch (error) {
        this.isLoading = false
        this.hasError = true
        this.errorMessage = this.getErrorMessage(error)
        console.error('Lottie animation failed to load:', error)
        this.$emit('animationError', error)
      }
    },
    destroyAnimation() {
      if (this.animation) {
        this.animation.removeEventListener('complete', this.onComplete)
        this.animation.removeEventListener('loopComplete', this.onLoopComplete)
        this.animation.removeEventListener('enterFrame', this.onEnterFrame)
        this.animation.destroy()
        this.animation = null
      }
    },
    setupHoverEvents() {
      this.$refs.lottieContainer.addEventListener('mouseenter', this.onMouseEnter)
      this.$refs.lottieContainer.addEventListener('mouseleave', this.onMouseLeave)
    },
    onMouseEnter() {
      if (this.hoverToPlay && this.animation) {
        this.isHovered = true
        this.animation.play()
        this.$emit('hoverStart')
      }
    },
    onMouseLeave() {
      if (this.hoverToPlay && this.animation) {
        this.isHovered = false
        this.animation.pause()
        this.$emit('hoverEnd')
      }
    },
    onComplete() {
      this.$emit('complete')
    },
    onLoopComplete() {
      this.$emit('loopComplete')
    },
    onEnterFrame(event) {
      this.$emit('enterFrame', event)
    },
    // 公共方法
    play() {
      if (this.animation) {
        this.animation.play()
      }
    },
    pause() {
      if (this.animation) {
        this.animation.pause()
      }
    },
    stop() {
      if (this.animation) {
        this.animation.stop()
      }
    },
    goToAndStop(frame) {
      if (this.animation) {
        this.animation.goToAndStop(frame, true)
      }
    },
    goToAndPlay(frame) {
      if (this.animation) {
        this.animation.goToAndPlay(frame, true)
      }
    },
    setSpeed(speed) {
      if (this.animation) {
        this.animation.setSpeed(speed)
      }
    },
    setDirection(direction) {
      if (this.animation) {
        this.animation.setDirection(direction)
      }
    },
    playSegments(segments, forceFlag = false) {
      if (this.animation) {
        this.animation.playSegments(segments, forceFlag)
      }
    },
    
    // 重试加载动画
    async retry() {
      if (this.retryCount >= this.maxRetries) {
        this.errorMessage = `重试次数已达上限 (${this.maxRetries})`
        return
      }
      
      this.isRetrying = true
      this.retryCount++
      
      // 延迟重试
      await new Promise(resolve => setTimeout(resolve, this.retryDelay))
      
      this.isRetrying = false
      this.destroyAnimation()
      await this.initAnimation()
    },
    
    // 获取友好的错误信息
    getErrorMessage(error) {
      if (error.message.includes('HTTP')) {
        return '动画文件加载失败，请检查网络连接'
      }
      if (error.message.includes('JSON')) {
        return '动画文件格式错误'
      }
      if (error.message.includes('无效的动画数据')) {
        return '动画数据无效'
      }
      return '动画加载失败，请稍后重试'
    },
    
    // 动画数据准备就绪
    onDataReady() {
      this.isLoading = false
      this.$emit('dataReady')
    },
    
    // 动画数据加载失败
    onDataFailed(error) {
      this.isLoading = false
      this.hasError = true
      this.errorMessage = '动画数据加载失败'
      this.$emit('dataFailed', error)
    }
  }
}
</script>

<style scoped>
.lottie-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.lottie-container.clickable {
  cursor: pointer;
}

.lottie-container.hoverable:hover {
  transform: scale(1.05);
  transition: transform 0.3s ease;
}

/* 加载状态样式 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(2px);
  z-index: 10;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(102, 126, 234, 0.2);
  border-top: 3px solid var(--primary-end, #667eea);
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 12px;
}

.loading-text {
  color: var(--text-primary, #333);
  font-size: 14px;
  margin: 0;
  opacity: 0.8;
}

/* 错误状态样式 */
.error-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(2px);
  z-index: 10;
  padding: 20px;
  text-align: center;
}

.error-icon {
  font-size: 32px;
  margin-bottom: 12px;
  opacity: 0.8;
}

.error-message {
  color: var(--text-error, #ef4444);
  font-size: 14px;
  margin: 0 0 16px 0;
  line-height: 1.4;
}

.retry-button {
  background: var(--primary-gradient, linear-gradient(135deg, #667eea 0%, #764ba2 100%));
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 80px;
}

.retry-button:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}

.retry-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

/* 加载和错误状态下隐藏动画容器内容 */
.lottie-container.loading > *:not(.loading-overlay),
.lottie-container.error > *:not(.error-overlay) {
  opacity: 0.3;
  pointer-events: none;
}

/* 旋转动画 */
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .loading-spinner {
    width: 24px;
    height: 24px;
    border-width: 2px;
  }
  
  .loading-text,
  .error-message {
    font-size: 12px;
  }
  
  .error-icon {
    font-size: 24px;
  }
  
  .retry-button {
    padding: 6px 12px;
    font-size: 12px;
  }
}

.lottie-container svg,
.lottie-container canvas {
  max-width: 100%;
  max-height: 100%;
}
</style>